﻿using System.Collections.Generic;
using Handler;
using NetBrick.Client;
using NetBrick.Common;
using UniBrickCommon;
using UniBrickCommon.Packets;
using UnityEngine;

public abstract class UniBrickClient : Client
{
    public static UniBrickClient Instance { get; private set; }

    protected UniBrickClient() : base(CommonConstants.AppName)
    {
        Instance = this;
    }

    protected override void Init()
    {
        // Initialize the client.
        RegisterPackets();
        RegisterHandlers();
    }

    private static void RegisterPackets()
    {
        // Register those packets.
        Packet.Instance.Register(UniBrickPacketCode.AuthenticateRequest, typeof(AuthenticatePacket.Request));
        Packet.Instance.Register(UniBrickPacketCode.AuthenticateResponse, typeof(AuthenticatePacket.Response));
        Packet.Instance.Register(UniBrickPacketCode.UpdateEvent, typeof(UpdatePacket.Event));
        Packet.Instance.Register(UniBrickPacketCode.UpdateRequest, typeof(UpdatePacket.Request));
        Packet.Instance.Register(UniBrickPacketCode.UpdatePlayerList, typeof(UpdatePlayerListPacket));
    }

    private void RegisterHandlers()
    {
        // Register all those handlers.
        AddPacketHandler(UniBrickPacketCode.AuthenticateResponse, new AuthenticateResponseHandler(this));
        AddPacketHandler(UniBrickPacketCode.UpdateEvent, new UpdateEventHandler(this));
        AddPacketHandler(UniBrickPacketCode.UpdatePlayerList, new UpdatePlayerListHandler(this));
    } 

    public override void DebugInfo(string message, params object[] arg)
    {
        Debug.LogFormat(message, arg);
    }

    public override void DebugWarn(string message, params object[] arg)
    {
        Debug.LogWarningFormat(message, arg);
    }

    public override void DebugError(string message, params object[] arg)
    {
        Debug.LogErrorFormat(message, arg);
    }

    public override void DebugSevere(string message, params object[] arg)
    {
        Debug.LogErrorFormat(message, arg);
    }

    protected override void OnDisconnect(string reason)
    {
        // Disconnected from the server.
        DebugInfo("Disconnected - {0}", reason);
    }

    protected override void OnConnect()
    {
        // Successfully connected to the server.
        DebugInfo("Connected.");
        EstablishEncryption();
    }

    public abstract void UpdatePlayer(string username, Vector3 position, Quaternion rotation);

    public abstract void UpdatePlayers(List<string> playerList);

    public abstract void CreatePlayer(string playerName);
    public abstract void RemovePlayer(string playerName);
}